#include <iostream>
#include <stdio.h>
#include "Plugins/imageHelper/cImageHelper.h"
#include "Plugins/dirHelper/cDirHelper.h"
#include "cAutoDeleter.h"

using namespace libtool_sdk;
using namespace libtool_sdk::Helper;


void test_jpeg_decompress_to_bmp(unsigned char* pJpgData, unsigned int iJpgSize)
{
    unsigned char* pBmpData = NULL;
    unsigned long iBmpSize = 0;
    int iWidth = 0;
    int iHeight = 0;
    int iRet = jpeg_decompress_to_bmp(pJpgData, iJpgSize, (void**)&pBmpData, &iBmpSize, &iWidth, &iHeight);
    printf("jpeg_decompress_to_bmp ret = %d, pBmpData = %p, bmp len = %lu, width = %d, height = %d\n", iRet, pBmpData, iBmpSize, iWidth, iHeight);

    AutoRelease<unsigned char*, AUTORELEASE_ARR> autoRelease_bmp(pBmpData);

    const char* pDestBmpFile = "jpeg_decompress_to_bmp.bmp";
    if(iRet == 0 && pBmpData != NULL && iBmpSize > 0)
    {
        Tool_save_file(pDestBmpFile, pBmpData, iBmpSize);
    }
}

void test_jpeg_to_rgb24_to_bmp(unsigned char* pJpgData, unsigned int iJpgSize)
{
    unsigned char* pRGBData = NULL;
    unsigned long iRGBSize = 0;

    int iWidth = 0;
    int iHeight = 0;
    int iRet = jpeg_decompress_to_rgb24(pJpgData, iJpgSize, (void**)&pRGBData, &iRGBSize, &iWidth, &iHeight);
    printf("jpeg_decompress_to_rgb24 ret = %d, pRGBData = %p, rgb len = %lu, width = %d, height = %d\n", iRet, pRGBData, iRGBSize, iWidth, iHeight);

    AutoRelease<unsigned char*, AUTORELEASE_ARR> autoRelease_rgb(pRGBData);
    if(iRet == 0 && pRGBData!= NULL && iRGBSize > 0)
    {
        unsigned char* pBmpData = new unsigned char[iRGBSize+1024];
        int iBmpSize = iRGBSize + 1024;
        AutoRelease<unsigned char*, AUTORELEASE_ARR> autoRelease_bmp(pBmpData);

        printf("try simplest_bgr24_to_bmp\n");
        iRet = simplest_bgr24_to_bmp(pRGBData, iRGBSize, iWidth, iHeight, pBmpData, &iBmpSize);
        printf("simplest_bgr24_to_bmp ret = %d, pBmpData = %p, bmp len = %d\n", iRet, pBmpData, iBmpSize);

        const char* pDestBmpFile = "jpeg_to_rgb24_to_bmp.bmp";
        if(iRet == 0 && pBmpData!= NULL && iBmpSize > 0)
        {
            Tool_save_file(pDestBmpFile, pBmpData, iBmpSize);
        }
    }
    else
    {
        printf("jpeg_decompress_to_rgb24 failed\n");
    }    
}

void test_jpeg_resize_to_bmp(unsigned char* pJpgData, unsigned int iJpgSize)
{
    int iWidth = 0;
    int iHeight = 0;
    {
        unsigned char* pRGBData = NULL;
        unsigned long iRGBSize = 0;
        AutoRelease<unsigned char*, AUTORELEASE_ARR> autoRelease_rgb(pRGBData);
        int iRet = jpeg_decompress_to_rgb24(pJpgData, iJpgSize, (void**)&pRGBData, &iRGBSize, &iWidth, &iHeight);
        printf("jpeg_decompress_to_rgb24 ret = %d, pRGBData = %p, rgb len = %lu, width = %d, height = %d\n", iRet, pRGBData, iRGBSize, iWidth, iHeight);
    }
    unsigned char* pBmpData = NULL;
    unsigned long iBmpSize = 0;
    int iRet = jpeg_resize_to_bmp(pJpgData, iJpgSize, iWidth/2,  iHeight/2,  (void**)&pBmpData, &iBmpSize);
    printf("jpeg_resize_to_bmp ret = %d, pBmpData = %p, bmp len = %lu\n", iRet, pBmpData, iBmpSize);

    AutoRelease<unsigned char*, AUTORELEASE_ARR> autoRelease_bmp(pBmpData);

    const char* pDestBmpFile = "jpeg_resize_to_bmp.bmp";
    if(iRet == 0 && pBmpData!= NULL && iBmpSize > 0)
    {
        Tool_save_file(pDestBmpFile, pBmpData, iBmpSize);
    }
}

void test_jpeg_resize(unsigned char* pJpgData, unsigned int iJpgSize)
{
    int iWidth = 0;
    int iHeight = 0;
    {
        unsigned char* pRGBData = NULL;
        unsigned long iRGBSize = 0;
        AutoRelease<unsigned char*, AUTORELEASE_ARR> autoRelease_rgb(pRGBData);
        int iRet = jpeg_decompress_to_rgb24(pJpgData, iJpgSize, (void**)&pRGBData, &iRGBSize, &iWidth, &iHeight);
        printf("jpeg_decompress_to_rgb24 ret = %d, pRGBData = %p, rgb len = %lu, width = %d, height = %d\n", iRet, pRGBData, iRGBSize, iWidth, iHeight);
    }
    unsigned char* pRisizeData = NULL;
    unsigned long iResizeSize = 0;
    int iRet = jpeg_resize(pJpgData, iJpgSize, iWidth/2, iHeight/2,(void**)&pRisizeData, &iResizeSize);
    printf("jpeg_resize ret = %d, pRisizeData = %p, resize len = %lu\n", iRet, pRisizeData, iResizeSize);
    AutoRelease<unsigned char*, AUTORELEASE_ARR> autoRelease_resize(pRisizeData);
    const char* pDestJpgFile = "jpeg_resize.jpg";
    if(iRet == 0 && pRisizeData!= NULL && iResizeSize > 0)
    {
        Tool_save_file(pDestJpgFile, pRisizeData, iResizeSize);
    }
}

void test_jpg_fuction(const char* pSrcJpgFile)
{
    const char* pSrcJPG = pSrcJpgFile;
    unsigned int iJpgSize = 1024*1024;
    unsigned char* pJpgData = new unsigned char[iJpgSize];

    AutoRelease<unsigned char*, AUTORELEASE_ARR> autoRelease_jpg(pJpgData);

    if(!Tool_loadFile(pSrcJPG, pJpgData, &iJpgSize))
    {
        printf("load jpg failed\n");
        return;
    }
    printf("load jpg success, jpg len = %u\n", iJpgSize);
    test_jpeg_decompress_to_bmp(pJpgData, iJpgSize);
    test_jpeg_to_rgb24_to_bmp(pJpgData, iJpgSize);
    test_jpeg_resize_to_bmp(pJpgData, iJpgSize);
    test_jpeg_resize(pJpgData, iJpgSize);
}

void test_Bmp_to_jpeg(unsigned char* pBmpData, unsigned int iBmpSize)
{
    unsigned char* pJpgData = NULL;
    unsigned long iJpgSize = 0;    
    int iRet = Bmp_to_jpeg(pBmpData, iBmpSize, (void**)&pJpgData, &iJpgSize);
    printf("Bmp_to_jpeg ret = %d, pJpgData = %p, jpg len = %lu\n", iRet, pJpgData, iJpgSize);
    AutoRelease<unsigned char*, AUTORELEASE_ARR> autoRelease_jpg(pJpgData);
    const char* pDestJpgFile = "Bmp_to_jpeg.jpg";
    if(iRet == 0 && pJpgData!= NULL && iJpgSize > 0)
    {
        Tool_save_file(pDestJpgFile, pJpgData, iJpgSize);
    }
}

void test_Bmp_to_jpeg_gray(unsigned char* pBmpData, unsigned int iBmpSize)
{
    unsigned char* pJpgData = NULL;
    unsigned long iJpgSize = 0;    
    int iRet = Bmp_to_jpeg_gray(pBmpData, iBmpSize, &pJpgData, &iJpgSize);
    printf("Bmp_to_jpeg ret = %d, pJpgData = %p, jpg len = %lu\n", iRet, pJpgData, iJpgSize);
    AutoRelease<unsigned char*, AUTORELEASE_ARR> autoRelease_jpg(pJpgData);
    const char* pDestJpgFile = "Bmp_to_jpeg_gray.jpg";
    if(iRet == 0 && pJpgData!= NULL && iJpgSize > 0)
    {
        Tool_save_file(pDestJpgFile, pJpgData, iJpgSize);
    }
}


void test_bmp_function(const char* pSrcBmpFile)
{
    const char* pSrcBmp = pSrcBmpFile;
    unsigned int iBmpSize = 20*1024*1024;
    unsigned char* pBmpData = new unsigned char[iBmpSize];

    AutoRelease<unsigned char*, AUTORELEASE_ARR> autoRelease_bmp(pBmpData);

    if(!Tool_loadFile(pSrcBmp, pBmpData, &iBmpSize))
    {
        printf("load image failed\n");
        return;
    }
    printf("load image success, data len = %u\n", iBmpSize);

    test_Bmp_to_jpeg(pBmpData, iBmpSize);
    test_Bmp_to_jpeg_gray(pBmpData, iBmpSize);
}

int main(int argc, char* argv[]) 
{
    const char* pSrcJPGFile = "test.jpg";
    // test_jpg_fuction(pSrcJPGFile);

    const char* pSrcBmpFile = "test.bmp";
    // const char* pSrcBmpFile = "plate.bmp";
    test_bmp_function(pSrcBmpFile);
}

